﻿using Microsoft.Win32;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using SmartPlant.Core;
using SmartPlant.Core.Mvvm;
using SmartPlant.Model;
using SmartPlant.Model.DbContext.Biz;
using SmartPlant.Modules.Base.UIEntity;
using SmartPlant.Services;
using SmartPlant.Services.Interfaces;
using SmartPlant.WinCore;
using SmartPlant.WinCore.Helper;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Telerik.Windows.Controls;
using Telerik.Windows.Diagrams.Core;
using Unity;

namespace SmartPlant.Modules.Base.ViewModels
{
    public class SpecOutputViewModel : RegionViewModelBase
    {
        private DelegateCommand<object> _selectAllCommand;
        private DelegateCommand<object> _outputCommand;
        private DelegateCommand<object> _saveFileCommand;
        private string _busyContent = "数据导出中.....";
        private bool _isBusy;
        private readonly BackgroundWorker backgroundWorker;

        private readonly ITaskJobService _taskJobService;
        private readonly IAchievementService _specOutputService;
        private readonly IEventAggregator _eventAggregator;

        private ObservableCollection<ComponentFunctionTypeModel> _comFuncTypes;
        private ObservableCollection<ComboBoxItemModel<SimpleStringModel>> _templatePathList;
        private List<ITreeNodeModel> _currentNodes = null;

        public List<ComboBoxItemModel<SimpleStringModel>> ComboxList { get; set; } = new List<ComboBoxItemModel<SimpleStringModel>>();

        public ObservableCollection<ComboBoxItemModel<SimpleStringModel>> TemplatePathList
        {
            get { return _templatePathList; }
            set { SetProperty(ref _templatePathList, value); }
        }

        public SpecOutputViewModel(
            IEventAggregator eventAggregator,
            IRegionManager regionManager,
            IAchievementService specOutputService,
            IDialogService dialog,
            IUnityContainer unityContainer)
           : base(regionManager, unityContainer, dialog)
        {
            _taskJobService = unityContainer.Resolve<TaskJobService>();
            _specOutputService = specOutputService;
            _isOutputPdf = false;
            _comFuncTypes = new ObservableCollection<ComponentFunctionTypeModel>();
            _eventAggregator = eventAggregator;
            _eventAggregator.GetEvent<PlanSelectedEvent>().Subscribe(OnPlanSelectedEvent);
            ComboxList.Add(new ComboBoxItemModel<SimpleStringModel> { Description = "分单元出图", IsEnable = true, SelectedModel = new SimpleStringModel { v1 = "0" } });
            ComboxList.Add(new ComboBoxItemModel<SimpleStringModel> { Description = "合并出图", IsEnable = true, SelectedModel = new SimpleStringModel { v1 = "1" } });
            this.SelectedModel = ComboxList[0].SelectedModel;

            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += this.OnBackgroundWorkerDoWork;
            backgroundWorker.RunWorkerCompleted += OnBackgroundWorkerRunWorkerCompleted;

            if (GlobalObject.CurrentNodes != null && GlobalObject.CurrentNodes.Count > 0)
            {
                OnPlanSelectedEvent(GlobalObject.CurrentNodes);
            }
        }

        private async void OnPlanSelectedEvent(List<ITreeNodeModel> treeNodes)
        {
            _currentNodes = treeNodes;
            string units = _currentNodes.ExpandToString(t => t.Id, ",");
            await RefreshData(units);
        }

        //protected override async void OnInitPage(object obj)
        //{
        //    base.OnInitPage(obj);
        //    var str = await _specOutputService.SpecOutputTemplatePath(GlobalObject.CurrentProject.ProjId.ToString());
        //    var list = new ObservableCollection<ComboBoxItemModel<SimpleStringModel>>();

        //    if (str != null && str.Count > 0)
        //    {
        //        foreach (var item in str)
        //        {
        //            list.Add(new ComboBoxItemModel<SimpleStringModel>
        //            {
        //                Name = item,
        //                Description = item,
        //                IsEnable = true,
        //                SelectedModel = new SimpleStringModel { v1 = item }
        //            });
        //        }
        //    }

        //    TemplatePathList = list;
        //    if (list.Count > 0)
        //    {
        //        SelectedTempateModel = list[0].SelectedModel;
        //    }
        //}

        /// <summary>
        /// 用于显示数据获取的进度文本。
        /// </summary>
        public string BusyContent
        {
            get { return _busyContent; }
            set { SetProperty(ref _busyContent, value); }
        }
        /// <summary>
        /// 当前是否处理忙碌状态。
        /// </summary>
        public virtual bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (this._isBusy != value)
                {
                    this._isBusy = value;
                    this.OnPropertyChanged(nameof(IsBusy));
                    if (_isBusy)
                    {
                        backgroundWorker.RunWorkerAsync();
                    }
                }
            }
        }

        private SimpleStringModel _selectedTemplateModel;
        public SimpleStringModel SelectedTempateModel
        {
            get { return _selectedTemplateModel; }
            set { SetProperty(ref _selectedTemplateModel, value); }
        }

        private SimpleStringModel _selectedModel;
        public SimpleStringModel SelectedModel
        {
            get { return _selectedModel; }
            set { SetProperty(ref _selectedModel, value); }
        }

        private string _fielPath;
        public string FilePath
        {
            get { return _fielPath; }
            set { SetProperty(ref _fielPath, value); }
        }

        private bool _isOutputPdf;
        public bool IsOutputPdf
        {
            get { return _isOutputPdf; }
            set { SetProperty(ref _isOutputPdf, value); }
        }

        private bool _isSelectedAll;
        public bool IsSelectedAll
        {
            get { return _isSelectedAll; }
            set { SetProperty(ref _isSelectedAll, value); }
        }

        public ObservableCollection<ComponentFunctionTypeModel> ComFuncTypes
        {
            get
            {
                return _comFuncTypes;
            }
            set { SetProperty(ref _comFuncTypes, value); }
        }

        public System.Windows.Input.ICommand OutputCommand
        {
            get
            {
                if (_outputCommand != null) return _outputCommand;
                _outputCommand = new DelegateCommand<object>(onOutputCommand);
                return _outputCommand;
            }
        }

        public System.Windows.Input.ICommand SaveFileCommand
        {
            get
            {
                if (_saveFileCommand != null) return _saveFileCommand;
                _saveFileCommand = new DelegateCommand<object>(onSaveFileCommandAsync);
                return _saveFileCommand;
            }
        }


        public System.Windows.Input.ICommand SelectAllCommand
        {
            get
            {
                if (_selectAllCommand != null) return _selectAllCommand;
                _selectAllCommand = new DelegateCommand<object>(onSelectAllCommandAsync);
                return _selectAllCommand;
            }
        }

        private void onSaveFileCommandAsync(object obj)
        {
            var saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Zip压缩文件|*.zip";
            var r = saveFileDialog.ShowDialog();
            if (r.HasValue)
            {
                FilePath = saveFileDialog.FileName;
            }
        }

        protected async Task RefreshData(string unitIds)
        {
            string proId = GlobalObject.CurrentProject.ProjId.ToString();

            var list = await _specOutputService.GetSpecOutputPreviewAsync(proId, unitIds);
            List<ComponentFunctionTypeModel> model = list.MapToList<ComponentFunctionTypeModel>();
            _comFuncTypes.Clear();
            if (model != null)
                _comFuncTypes.AddRange(model);
        }

        private void onSelectAllCommandAsync(object obj)
        {
            ComFuncTypes.ForEach(model =>
            {
                model.IsSelect = IsSelectedAll;
            });
        }

        private void onOutputCommand(object obj)
        {
            if (_fielPath.IsNullOrEmpty())
            {
                var message = "导出文件本地保存路径不能为空！！！";
                Dialog.ShowAltert(message);
                return;
            }
            //if (SelectedTempateModel == null)
            //{
            //    var message = "导出文件需选择服务器路径模板！！！";
            //    Dialog.ShowAltert(message);
            //    return;
            //}

            if (_currentNodes == null)
            {
                Dialog.ShowAltert("导出前请至少选择一个单元！！！");
                return;
            }
            string units = _currentNodes.ExpandToString(t => t.Id, ",");
            if (units.IsNullOrEmpty())
            {
                Dialog.ShowAltert("导出前请至少选择一个单元！！！");
                return;
            }
            var types = _comFuncTypes.AsQueryable().Where(f => f.IsSelect).ToList();
            string insttypeids = types.ExpandToString(t => t.CmpntFuncTypeId, ",");
            if (insttypeids.IsNullOrEmpty())
            {
                Dialog.ShowAltert("导出前请至少选择一类仪表！！！");
                return;
            }
            this.IsBusy = true;
        }

        /// <summary>
        /// 后台任务数据加载完成执行的方法。
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            InvokeOnUIThread(() =>
            {
                var result = e.Result as RESTfulResult;
                this.IsBusy = false;
                if (result.succeeded)
                {
                    Dialog.ShowMessage(result.msg);
                }
                else
                {
                    Dialog.ShowAltert(result.msg);
                }

            });
        }

        private void OnBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            var task = ExportFileAsync(null);
            while (!task.IsCompleted)
            {
                Thread.Sleep(1000);
            }
            e.Result = task.Result;
        }

        /// <summary>
        /// 执行后台视图数据加载服务。
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        protected async virtual Task<object> ExportFileAsync(object model)
        {
            string units = _currentNodes.ExpandToString(t => t.Id, ",");
            var types = _comFuncTypes.AsQueryable().Where(f => f.IsSelect).ToList();
            string insttypeids = types.ExpandToString(t => t.CmpntFuncTypeId, ",");
            bool exportflag = SelectedModel.v1 == "0";
            var proid = GlobalObject.CurrentProject.ProjId.ToString();
            var proName=GlobalObject.CurrentProject.ProjName.ToString();
            var result = new RESTfulResult { succeeded = false };
            try
            {
                var rr = await _specOutputService.SpecOutputAsync(proid, proName, units, insttypeids, exportflag);

                if (!rr.succeeded)
                {
                    LoggerHelper.Current.Error(rr.errors.ToString());
                    result.msg = rr.errors.ToString();
                    return result;
                }

                var taskId = rr.data;

                while (true)
                {
                    try
                    {
                        TaskJob task = await _taskJobService.GetJobAsync(GlobalObject.CurrentProject.ProjId.ToString(), taskId);
                        if (task != null)
                        {
                            if (task.FINISHED == 1)
                            {
                                break;//结束了，且成功
                            }
                            else if (task.FINISHED == -1)
                            {
                                string msg = $"导出规格书失败：{task.NOTE}";
                                result.msg = msg;
                                return result;
                                //结束了，但是中途错误
                            }
                            BusyContent = $"导出中...正在处理{task.NOTE}";
                            Thread.Sleep(2000);
                        }
                        else
                        {
                            string msg = $"无法查询到任务{taskId}";
                            result.msg = msg;
                            return result;

                        }

                    }
                    catch (Exception x)
                    {
                        string msg = $"导出规格书失败：{x.Message}";
                        LoggerHelper.Current.Error(msg, x);
                        result.msg = msg;
                        return result;
                    }
                }

                var rFile = await _taskJobService.DownloadFileAsync(GlobalObject.CurrentProject.ProjId.ToString(), taskId);

                if (!rFile.succeeded)
                {
                    rr.msg = rFile.msg;
                    return rr;
                }
                var content = Convert.FromBase64String(rFile.data.Data);

                FileHelper.WriteFileBinary(_fielPath, content);

                //using var stream = rr.data;
                //var r = await FileHelper.WriteFileStreamAsync(stream, _fielPath);
                result.msg = "导出文件到本地成功！！！";
                result.succeeded = true;
                return result;
            }
            catch (Exception x)
            {
                var xMessage = $"导出文件到本地失败：{x.Message}！！！";
                LoggerHelper.Current.Error(xMessage, x);
                result.msg = xMessage;
                return result;
            }
        }
    }
}
